package model

import (
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
	"mime/multipart"
	"nspel/entity"
	"nspel/util"
	"time"
)

type PostAreasImport struct {
	ImportFile multipart.File
}

func (postAreasImport *PostAreasImport) Validate(c *beego.Controller) error {
	file, fileHeader, err := c.GetFile("import")
	if err != nil {
		return err
	}
	if !util.ValidateFileType(fileHeader, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
		return err
	}
	postAreasImport.ImportFile = file
	return nil
}

type PostAreaModify struct {
	Id             int64     `json:"id" valid:"Required;Min(1)"`
	SchoolNum      int64     `json:"schoolNum" valid:"Min(0)"`
	IsExperiment   bool      `json:"isExperiment"`
	JoinYear       int64     `json:"joinYear" valid:"Min(0)"`
	Contact        string    `json:"contact" valid:"MaxSize(10)"`
	ContactPhone   string    `json:"contactPhone"`
	ContactEmail   string    `json:"contactEmail"`
	ContactAddress string    `json:"contactAddress" valid:"MaxSize(255)"`
	ExperimentAt   time.Time `json:"experimentAt"`
	StandoutAt     time.Time `json:"standoutAt"`
}

type PostAreaNameValidateExist struct {
	ProvinceId int64  `json:"provinceId"`
	CityId     int64  `json:"cityId"`
	Name       string `json:"name" valid:"MinSize(1);MaxSize(20)"`
}

func (postAreaNameValidateExist *PostAreaNameValidateExist) Validate() (bool, error) {
	valid := validation.Validation{}
	b, err := valid.Valid(postAreaNameValidateExist)
	if err != nil || !b {
		return b, err
	}
	province := new(entity.Province)
	err = province.SelectAllById(postAreaNameValidateExist.ProvinceId)
	if err != nil {
		return false, err
	}
	city := new(entity.City)
	err = city.SelectAllById(postAreaNameValidateExist.CityId)
	if err != nil {
		return false, err
	}
	if city.ProvinceId != province.Id {
		return false, err
	}
	return true, nil
}

type PostAreaAdd struct {
	CountryId      int64     `json:"-"`
	ProvinceId     int64     `json:"provinceId"`
	CityId         int64     `json:"cityId"`
	Name           string    `json:"name" valid:"MinSize(1)"`
	SchoolNum      int64     `json:"schoolNum" valid:"Min(0)"`
	IsExperiment   bool      `json:"isExperiment"`
	JoinYear       int64     `json:"joinYear" valid:"Min(0)"`
	Contact        string    `json:"contact" valid:"MaxSize(10)"`
	ContactPhone   string    `json:"contactPhone"`
	ContactEmail   string    `json:"contactEmail"`
	ContactAddress string    `json:"contactAddress" valid:"MaxSize(255)"`
	ExperimentAt   time.Time `json:"experimentAt"`
	StandoutAt     time.Time `json:"standoutAt"`
}

func (postAreaAdd *PostAreaAdd) Validate() (bool, error) {
	valid := validation.Validation{}
	b, err := valid.Valid(postAreaAdd)
	if err != nil || !b {
		return b, err
	}
	province := new(entity.Province)
	err = province.SelectAllById(postAreaAdd.ProvinceId)
	if err != nil {
		return false, err
	}
	city := new(entity.City)
	err = city.SelectAllById(postAreaAdd.CityId)
	if err != nil {
		return false, err
	}
	if city.ProvinceId != province.Id {
		return false, nil
	}
	postAreaAdd.CountryId = province.CountryId
	if postAreaAdd.JoinYear <= 2000 && postAreaAdd.JoinYear != 0 {
		return false, nil
	}
	area := new(entity.Area)
	err = area.SelectAllByCityIdName(postAreaAdd.CityId, postAreaAdd.Name)
	if err == nil {
		return false, nil
	}
	if err != nil && err != orm.ErrNoRows {
		return false, err
	}
	if len(postAreaAdd.ContactPhone) > 0 {
		valid.Phone(postAreaAdd.ContactPhone, "contact_phone")
		if valid.HasErrors() {
			return false, nil
		}
		manager := new(entity.Manager)
		err = manager.SelectAllByUserName(postAreaAdd.ContactPhone)
		if err == nil {
			return false, nil
		} else if err != nil && err != orm.ErrNoRows {
			return false, err
		}
	}
	if len(postAreaAdd.ContactEmail) > 0 {
		valid.Email(postAreaAdd.ContactEmail, "contact_email")
		if valid.HasErrors() {
			return false, nil
		}
	}
	return true, nil
}

type DeleteArea struct {
	Id []int64 `json:"id"`
}

func (deleteArea *DeleteArea) Validate() (bool, error, []entity.Area) {
	var areas []entity.Area
	if len(deleteArea.Id) == 0 {
		return false, nil, nil
	}
	for i := 0; i < len(deleteArea.Id); i++ {
		area := new(entity.Area)
		err := area.SelectAllById(deleteArea.Id[i])
		if err != nil {
			return false, err, nil
		}
		areas = append(areas, *area)
		school := new(entity.School)
		err, schools := school.SelectAllByAreaId(deleteArea.Id[i])
		if err != nil {
			return false, err, nil
		} else if len(schools) != 0 {
			return false, nil, nil
		}
	}
	return true, nil, areas
}

type GetAreasList struct {
	ProvinceId  int64
	CityId      int64
	AreaName    string
	JoinYear    int64
	PageSize    int64
	CurrentPage int64
}

func (getAreasList *GetAreasList) Validate(provinceId string, cityId string, areaName string, joinYear string, pageSize string, currentPage string, c *beego.Controller) bool {
	var err error
	getAreasList.ProvinceId, err = c.GetInt64(provinceId)
	if err != nil {
		return false
	}
	getAreasList.CityId, err = c.GetInt64(cityId)
	if err != nil {
		return false
	}
	getAreasList.AreaName = c.GetString(areaName)
	getAreasList.JoinYear, err = c.GetInt64(joinYear)
	if err != nil {
		return false
	}
	getAreasList.PageSize, err = c.GetInt64(pageSize)
	if err != nil {
		return false
	}
	getAreasList.CurrentPage, err = c.GetInt64(currentPage)
	if err != nil {
		return false
	}
	return true
}

type GetAreaExportReq struct {
	ProvinceId int64
	CityId     int64
	AreaName   string
	JoinYear   int64
	Id         []int64
}

func (getAreaExportReq *GetAreaExportReq) Validate(provinceId string, cityId string, areaName string, joinYear string, c *beego.Controller) bool {
	var err error
	getAreaExportReq.ProvinceId, err = c.GetInt64(provinceId)
	if err != nil {
		return false
	}
	getAreaExportReq.CityId, err = c.GetInt64(cityId)
	if err != nil {
		return false
	}
	getAreaExportReq.AreaName = c.GetString(areaName)
	getAreaExportReq.JoinYear, err = c.GetInt64(joinYear)
	if err != nil {
		return false
	}
	return true
}
